/*
https://www.luogu.com.cn/problem/P1443
作业–马的遍历代码实现：
•用walk 数组存下八个方向的偏移量
•ans[i][j] 数组记录位置(i,j) 是第几次访问到，初始化为-1
•往8 个方向枚举，新坐标是老坐标加上偏移量。
•若坐标超过地图范围或者该点已被访问过则无需入队
•入队前将新的坐标的答案写入到ans对应的位置
•输出整数宽度5 位，左对齐：
*/
#include <bits/stdc++.h>
using namespace std;
struct Pos { //一个结构体存储x,y两个坐标
    int x, y;
    Pos(int ax = 0, int ay = 0) {
        x = ax; y = ay;
    }
};
const int maxn = 405;
queue<Pos> Q;//队列
int ans[maxn][maxn];//记录答案，-1表示未访问
int n, m, sx, sy;
int walk[8][2] = {{2, 1}, {1, 2}, {-1, 2}, {-2, 1},
    {-2, -1}, {-1, -2}, {1, -2}, {2, -1}
};

int main() {
    cin >> n >> m >> sx >> sy;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            ans[i][j] = -1; // 答案都初始化为未访问过
    Q.push(Pos(sx, sy)); // 使起点入队扩展
    ans[sx][sy] = 0;
    while (!Q.empty()) { // 循环直到队列为空
        Pos now = Q.front();  // 拿出队首以扩展
        Q.pop();
        for (int k = 0; k < 8; k++) {
            int x = now.x + walk[k][0], y = now.y + walk[k][1]; // 计算新坐标 x 和 y
            int d = ans[now.x][now.y]; // d 是目前点的走几步的结果
            if (x < 1 || x > n || y < 1 || y > m || ans[x][y] != -1)
                continue;  // 若坐标超过地图范围或者该点已被访问过则无需入队
            ans[x][y] = d + 1;  // 记录下一个点的答案，是目前点多走一步的结果。
            Q.push(Pos(x, y));
        }
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++)
            printf("%-5d", ans[i][j]); // 输出第 i 行第 j 列答案，整数宽度 5 位
        puts(""); // 输出换行
    }
}

/*
g++ bfs/bfs_5.cpp && echo "3 3 1 1" | ./a.out
*/